package sharetime.web.controllers;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sharetime.core.pager.Pager;
import sharetime.core.pager.PagerException;

@SuppressWarnings("unchecked")
public class PagerPaginationSupport {

	private static final Logger logger = LoggerFactory
			.getLogger(PagerPaginationSupport.class);
	
	private Pager items;
	private int startIndex;
	private int countOnEachPage;
	public static int DEFAULT_COUNT_ON_EACH_PAGE = 10;
	public List page;
	public Integer pagerSize;
	public int nextStartIndexes[];
	public int previousStartIndexes[];
	private boolean tryNext;

	public PagerPaginationSupport() {
		this(DEFAULT_COUNT_ON_EACH_PAGE);
	}

	public PagerPaginationSupport(int countOnEachPage) {
		startIndex = 0;
		if (countOnEachPage < 1) {
			throw new IllegalArgumentException(
					"Count should be greater than zero!");
		} else {
			this.countOnEachPage = countOnEachPage;
			return;
		}
	}

	public int getCountOnEachPage() {
		return countOnEachPage;
	}

	public Pager getItems() {
		return items;
	}

	public void setItems(Pager items) {
		this.items = items;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
		page = null;
	}

	public int getEndIndex() {
		int endIndex = getStartIndex() + countOnEachPage;
		if (endIndex > getTotal())
			return getTotal();
		else
			return endIndex;
	}

	public int getStartIndex() {
		if (startIndex < 0)
			return 0;
		else
			return startIndex;
	}

	public int getStartIndexValue() {
		return startIndex;
	}

	public int getNextIndex() {
		int nextIndexes[] = getNextStartIndexes();
		if (nextIndexes == null)
			return 0;
		if (nextIndexes.length == 0) {
			if (items != null && !items.onLastPage())
				return items.getIndexOfFirstItemInCurrentPage()
						+ items.getCurrentPage().size();
			else
				return 0;
		} else {
			return nextIndexes[0];
		}
	}

	public int getPreviousIndex() {
		int previousIndexes[] = getPreviousStartIndexes();
		if (previousIndexes.length == 0)
			return 0;
		else
			return previousIndexes[previousIndexes.length - 1];
	}

	public int[] getNextStartIndexes() {
		if (nextStartIndexes != null)
			return nextStartIndexes;
		if (items == null || items.isEmpty())
			return new int[0];
		int index = getEndIndex();
		if (index == getTotal() && items.onLastPage())
			return null;
		int count = (getTotal() - index) / countOnEachPage;
		if ((getTotal() - index) % countOnEachPage > 0)
			count++;
		nextStartIndexes = new int[count];
		for (int i = 0; i < count; i++) {
			nextStartIndexes[i] = index;
			index += countOnEachPage;
		}

		return nextStartIndexes;
	}

	public int[] getPreviousStartIndexes() {
		if (previousStartIndexes != null)
			return previousStartIndexes;
		if (items == null || items.isEmpty())
			return new int[0];
		int index = getStartIndex();
		if (index == 0)
			return null;
		int count = index / countOnEachPage;
		if (index % countOnEachPage > 0)
			count++;
		previousStartIndexes = new int[count];
		for (int i = count - 1; i > 0; i--) {
			index -= countOnEachPage;
			previousStartIndexes[i] = index;
		}

		return previousStartIndexes;
	}

	public int getNiceStartIndex() {
		return getStartIndex() + 1;
	}

	public List getPage() {
		if (page == null) {
			if (items == null)
				return null;
			if (getStartIndex() >= items.getCurrentPage().size())
				loadMoreDataFromPager();
			page = new ArrayList();
			if (tryNext)
				try {
					items.skipTo(items.getCurrentPage().size() + 1);
				} catch (PagerException e) {
					logger.error(e.getMessage());
				}
			List cache = items.getCurrentPage();
			if (!cache.isEmpty())
				page = cache.subList(getStartIndex()
						- items.getIndexOfFirstItemInCurrentPage(),
						getEndIndex()
								- items.getIndexOfFirstItemInCurrentPage());
		}
		return page;
	}

	private void loadMoreDataFromPager() {
		try {
			items.skipTo(getStartIndex());
		} catch (PagerException e) {
			logger.error(e.getMessage());
		}
	}

	public int getTotal() {
		if (pagerSize == null && items != null)
			pagerSize = new Integer(items.getCurrentPage().size());
		if (pagerSize == null)
			return 0;
		else
			return pagerSize.intValue()
					+ items.getIndexOfFirstItemInCurrentPage();
	}

	public void skipTo(int indexPosition) {
		try {
			items.skipTo(indexPosition);
		} catch (PagerException e) {
		}
	}

	public boolean isTryNext() {
		return tryNext;
	}

	public void setTryNext(boolean tryNext) {
		this.tryNext = tryNext;
	}

}
